// 需求： 我们需要一个小弹窗 可能有几种不同的形式 确认型弹窗 取消型弹窗 提示型弹窗  弹窗的内容及颜色各不相同
// 首先分析问题， 针对这几个类型的弹窗 我们首先想到的是 创建几个类
function InfoPopup(content, colo) {}
function ConfirmPopup(content, colo) {}
function cancelPopup(content, colo) {}

// 然后对每一个类 通过new的方式 获取到每一个对象
let infoPopup1 = new infoPopup(content, color);
let infoPopup2 = new infoPopup(content, color);
let confirmPopup1 = new confirmPopup(content, color);

// 但是 如果我们使用工厂模式呢
function popup(type,content,color) {
    switch(type) {
        case 'infoPopup': 
            return new InfoPopup(content,color);
        case 'confirmPopup':
            return new ConfirmPopup(content,color);
        case 'cancelPopup':
            return new CanclePopup(content,color)
    }
}

// switch的方式不够优雅 改造成面向对象的方式
function popup(type,content,color) {
    // 使用new的方式创建对象
    if(this instanceof popup) {
        return new this[type](content,color);
    }else {
        // 如果不是new的方式调用
        return new popup(type,content,color);
    }
}   
// 各种类型的弹窗全部挂载在原型上成为实例方法
popup.prototype.infoPopup = function(content,color) {}
popup.prototype.confirmPopup = function(content,color) {}
popup.prototype.cancelPopup = function(content,color) {}


// 封装成模块
// 这个popup可以直接作为模块export出去给别人调用 也可以挂载在window上作为一个模块给别人调用。
// 因为popup封装了弹窗的各种细节 即使以后popup内部改了 或者 新增了弹窗类型 或者弹窗类的名字改了 
// 只要保证对外的接口参数不变 对外面都没有影响。挂载在window上作为模块可以使用自执行函数

(function() {
    function popup(type,content,color) {
        // 使用new的方式创建对象
        if(this instanceof popup) {
            return new this[type](content,color);
        }else {
            // 如果不是new的方式调用
            return new popup(type,content,color);
        }
    } 

    popup.prototype.infoPopup = function(content,color) {}
    popup.prototype.confirmPopup = function(content,color) {}
    popup.prototype.cancelPopup = function(content,color) {}

    // 挂载在window上
    window.popup = popup;
})();
// 外面可以直接使用
// 给函数里面传递参数 函数直接返回对象
let infoPopup1 = popup('infoPopup',content,color);

